//
//  MSQRCodeViewController.m
//  MSQRCode
//
//  Created by iOS on 2017/10/17.
//  Copyright © 2017年 MS. All rights reserved.
//

#import "MSQRCodeViewController.h"
#import <AVFoundation/AVFoundation.h>
#import <AudioToolbox/AudioToolbox.h>

#define kSCREEN_HEIGHT [UIScreen mainScreen].bounds.size.height
#define kSCREEN_WIDTH [UIScreen mainScreen].bounds.size.width
#define kSCREEN_BOUNDS [UIScreen mainScreen].bounds

#define kTOP (kSCREEN_HEIGHT - 220) / 2
#define kLEFT (kSCREEN_WIDTH - 220) / 2

/// 扫描区rect
#define kSCAN_RECT CGRectMake(kLEFT, kTOP, 220, 220)

@interface MSQRCodeViewController () <AVCaptureMetadataOutputObjectsDelegate>

@property (nonatomic) int num;
@property (nonatomic) BOOL upOrDown;
@property (strong, nonatomic) NSTimer *timer;
/// 透明遮罩
@property (strong, nonatomic) CAShapeLayer *cropLayer;
/// line
@property (strong, nonatomic) UIImageView *line;

/// device
@property (strong, nonatomic) AVCaptureDevice *device;
/// input
@property (strong, nonatomic) AVCaptureDeviceInput *input;
/// output
@property (strong, nonatomic) AVCaptureMetadataOutput *output;
/// session
@property (strong, nonatomic) AVCaptureSession *session;
/// Preview
@property (strong, nonatomic) AVCaptureVideoPreviewLayer *preview;

@end

@implementation MSQRCodeViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    [self initUI];
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self setCropRect:kSCAN_RECT];
    [self visitCamera];
}

- (void)initUI
{
    UIImageView *imgView = [[UIImageView alloc] initWithFrame:kSCAN_RECT];
    imgView.image = [UIImage imageNamed:@"MSQRCode_pick_bg"];
    [self.view addSubview:imgView];
    
    _upOrDown = NO;
    _num = 0;
    
    _line = [[UIImageView alloc] initWithFrame:CGRectMake(kLEFT, kTOP + 10, 220, 2)];
    _line.image = [UIImage imageNamed:@"MSQRCode_line"];
    [self.view addSubview:_line];
    
    _timer = [NSTimer scheduledTimerWithTimeInterval:.02 repeats:YES block:^(NSTimer * _Nonnull timer) {
        if (_upOrDown == NO)
        {
            _num ++;
            _line.frame = CGRectMake(kLEFT, kTOP + 10 + 2 * _num, 220, 2);
            if (2 * _num == 200)
            {
                _upOrDown = YES;
            }
        }
        else
        {
            _num --;
            _line.frame = CGRectMake(kLEFT, kAudioSessionProperty_OtherAudioIsPlaying + 10 + 2 * _num, 220, 2);
            if (_num == 0)
            {
                _upOrDown = NO;
            }
        }
    }];
}

- (void)setCropRect:(CGRect)cropRect
{
    _cropLayer = [[CAShapeLayer alloc] init];
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRect(path, nil, cropRect);
    CGPathAddRect(path, nil, self.view.bounds);
    
    [_cropLayer setFillRule:kCAFillRuleEvenOdd];
    [_cropLayer setPath:path];
    [_cropLayer setFillColor:[UIColor blackColor].CGColor];
    [_cropLayer setOpacity:0.6];
    
    
    [_cropLayer setNeedsDisplay];
    
    [self.view.layer addSublayer:_cropLayer];
}


#pragma mark - 访问照相机

- (void)visitCamera
{
    AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    if (device)
    {
        AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
        if (status == AVAuthorizationStatusNotDetermined)
        {
            [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
                if (granted)
                {
                    // 用户第一次同意了访问相机权限
                    dispatch_sync(dispatch_get_main_queue(), ^{
                        [self initDevice];
                    });
                }
                else
                {
                    // 用户第一次拒绝了访问相机权限
                    dispatch_sync(dispatch_get_main_queue(), ^{
                        // 停止扫描
                        [_session stopRunning];
                        [_timer setFireDate:[NSDate distantFuture]];
                        
                        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"用户拒绝了访问相机权限" preferredStyle:UIAlertControllerStyleAlert];
                        [alertController addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                            [self dismissQRCodeVC];
                        }]];
                        
                        [self presentViewController:alertController animated:YES completion:nil];
                    });
                }
            }];
        }
        else if (status == AVAuthorizationStatusAuthorized)
        {
            // 用户允许当前应用访问相机
            [self initDevice];
        }
        else if (status == AVAuthorizationStatusDenied)
        {
            // 用户拒绝当前应用访问相机
            NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
            NSString *message = [NSString stringWithFormat:@"请去-> [设置 - 隐私 - 相机 - %@] 开启权限", [infoDic objectForKey:@"CFBundleDisplayName"]];
            UIAlertController *alertC = [UIAlertController alertControllerWithTitle:@"相机权限未开启" message:message  preferredStyle:(UIAlertControllerStyleAlert)];
            
            UIAlertAction *cancelAlertAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
                [self dismissQRCodeVC];
            }];
            
            UIAlertAction *doneAlertAction = [UIAlertAction actionWithTitle:@"去设置" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
                NSString *URLStr = [NSString stringWithFormat:@"App-Prefs:root=%@", [infoDic objectForKey:@"CFBundleIdentifier"]];
                NSURL *URL = [NSURL URLWithString:URLStr];
                if ([[UIApplication sharedApplication] canOpenURL:URL])
                {
#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_10_0
                    [[UIApplication sharedApplication] openURL:URL options:@{} completionHandler:nil];
#else
                    [[UIApplication sharedApplication] openURL:URL];
#endif
                }
            }];
            
            [alertC addAction:cancelAlertAction];
            [alertC addAction:doneAlertAction];
            [self presentViewController:alertC animated:YES completion:nil];
            
        }
        else if (status == AVAuthorizationStatusRestricted)
        {
            // 因为系统原因, 无法访问相册
            UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"因为系统原因, 无法访问相册" preferredStyle:UIAlertControllerStyleAlert];
            [alertController addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {}]];
            
            [self presentViewController:alertController animated:YES completion:nil];
        }
    }
    else
    {
        // 设备没有摄像头
        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"设备没有摄像头" preferredStyle:UIAlertControllerStyleAlert];
        [alertController addAction:[UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {}]];
        
        [self presentViewController:alertController animated:YES completion:nil];
    }
}

- (void)initDevice
{
    // Device
    _device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];;
    // Input
    _input = [[AVCaptureDeviceInput alloc] initWithDevice:_device error:nil];
    // Output
    _output = [[AVCaptureMetadataOutput alloc] init];
    [_output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
    
    // 设置扫描区（top 与 left 互换  width 与 height 互换）
    CGFloat top = kTOP / kSCREEN_HEIGHT;
    CGFloat left = kLEFT/kSCREEN_WIDTH;
    CGFloat width = 220/kSCREEN_WIDTH;
    CGFloat height = 220/kSCREEN_HEIGHT;
    [_output setRectOfInterest:CGRectMake(top, left, height, width)];
    
    // Session
    _session = [[AVCaptureSession alloc] init];
    [_session setSessionPreset:AVCaptureSessionPresetHigh];
    // 添加输入流
    if ([_session canAddInput:_input])
    {
        [_session addInput:_input];
    }
    // 添加输出流
    if ([_session canAddOutput:_output])
    {
        [_session addOutput:_output];
    }
    
    // 设置条码类型
    _output.metadataObjectTypes = @[AVMetadataObjectTypeEAN13Code,
                                    AVMetadataObjectTypeEAN8Code,
                                    AVMetadataObjectTypeCode128Code,
                                    AVMetadataObjectTypeQRCode];
    // Preview
    _preview = [AVCaptureVideoPreviewLayer layerWithSession:_session];
    _preview.videoGravity = AVLayerVideoGravityResizeAspectFill;
    _preview.frame =self.view.layer.bounds;
    [self.view.layer insertSublayer:_preview atIndex:0];
    
    // Start
    [_session startRunning];
}


#pragma mark AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray *)metadataObjects fromConnection:(AVCaptureConnection *)connection
{
    NSString *stringValue;
    
    if ([metadataObjects count] >0)
    {
        // 停止扫描
        [_session stopRunning];
        [_timer setFireDate:[NSDate distantFuture]];
        /*
         // 开始扫描
         [_session startRunning];
         [timer setFireDate:[NSDate distantPast]];
         */
        
        AVMetadataMachineReadableCodeObject *metadataObject =  [metadataObjects objectAtIndex:0];
        stringValue = metadataObject.stringValue;
        
//        NSArray *arry = metadataObject.corners;
//        for (id temp in arry)
//        {
//            NSLog(@"%@",temp);
//        }
        [self playSystemSound];
        if (self.QRCodeComplete)
        {
            self.QRCodeComplete(stringValue);
        }
    }
    else
    {
        NSLog(@"无扫描信息");
        return;
    }
    
}


#pragma mark - Dismiss

- (void)dismissQRCodeVC
{
    [self dismissViewControllerAnimated:YES completion:nil];
}


#pragma mark - PalySound

- (void)playSystemSound
{
    // 当参数为:kSystemSoundID_Vibrate 时就是震动;当参数为 1000-2000 之间数字时就是播放系统声音
    SystemSoundID soundID = 1000;
    
    AudioServicesPlaySystemSoundWithCompletion(soundID, ^{

    });
    
//    AudioServicesPlayAlertSoundWithCompletion(soundID, ^{
//
//    });
}

- (void)palySoundName:(NSString *)name
{
    NSString *audioFile = [[NSBundle mainBundle] pathForResource:name ofType:nil];
    NSURL *fileUrl = [NSURL fileURLWithPath:audioFile];
    
    SystemSoundID soundID = 0;
    AudioServicesCreateSystemSoundID((__bridge CFURLRef)(fileUrl), &soundID);
    AudioServicesAddSystemSoundCompletion(soundID, NULL, NULL, soundCompleteCallback, NULL);
    AudioServicesPlaySystemSound(soundID); // 播放音效
}
void soundCompleteCallback(SystemSoundID soundID, void *clientData){
    // 播放成功回调
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
